package com.ynet.hmds28.service.controller;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.boot.hsf.lightapi.ConsumerService;
import com.alibaba.boot.hsf.lightapi.ServiceFactory;
import com.alibaba.fastjson.JSONObject;
import com.taobao.middleware.logger.Logger;
import com.taobao.middleware.logger.LoggerFactory;
import com.ynet.hm.merchant.domain.ContentBean;
import com.ynet.hm.user.domain.ServiceProvideBean;
import com.ynet.hm.user.service.IdentityAuthService;
import com.ynet.hm.user.service.OpenPlatformService;
import com.ynet.hm.user.service.PlatformFlowService;
import com.ynet.hm.user.service.QueryProvideByIdService;
import com.ynet.hm.utils.config.Result;
import com.ynet.hm.utils.config.ResultUtil;
import com.ynet.hm.utils.enums.ExceptionEnum;
import com.ynet.hm.utils.exception.MyException;
import com.ynet.hm.utils.rsa.RSAHelper;
import com.ynet.hmds28.service.invoke.InterfaceInvocationHandler;
import com.ynet.hmds28.service.mq.AliMQUtil;
import com.ynet.hmds28.service.redis.RedisService;

@RestController
public class MerchantController {

	private static final Logger logger = LoggerFactory
			.getLogger(MerchantController.class);
	
//	@Autowired
//	private QueryAirService queryAirService;
	@Autowired
	private OpenPlatformService openPlatformService;
	@Autowired
	private IdentityAuthService identityAuthService;
	@Autowired
	private PlatformFlowService platformFlowService;
	@Autowired
	private QueryProvideByIdService queryProvideByIdService;
	@Autowired
    private RedisService redisService;
	// 平台私钥
	@Value("${platformPrivateKey}")
	public String platformPrivateKey;
	@Autowired
	private AliMQUtil aliMQUtil;
    @Value("${topic}")
    public String topic;
    @Value("${tag}")
    public String tag;
    @Value("${spring.hsf.serviceGroup}")
	public String serviceGroup;
	@Value("${spring.hsf.timeout}")
	public int timeout;
	@Value("${spring.hsf.version}")
	public String version;

	/**
	 * 根据城市代码查询天气指数
	 * 
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/api/merchant/query", method = RequestMethod.POST)
	public Result<?> queryAir(@RequestBody Map<String, String> data) {
		
		String strBody = data.get("strBody");
		String oldstrBody = data.get("oldstrBody");
		ContentBean cBean = JSONObject.parseObject(oldstrBody, ContentBean.class);
		long startTime=System.currentTimeMillis();
		String provideId = cBean.getProvideId();
		String provideNum = provideId+"Num";
		
		if(!redisService.exists(provideNum)){
    		redisService.set(provideNum, 0);
    	}
		
		if(!((int)redisService.incr(provideNum,1)>Integer.valueOf(redisService.get(provideId).toString()))){
			logger.info("正常访问");
        }else{
            System.out.println("流量达到阈值，稍后再试");
            redisService.decr(provideNum,1);
            return ResultUtil.error(ExceptionEnum.QPS_IS_ERROR);
        }
		Map<String, String> map = new HashMap<String, String>();
		try {
			logger.info("资源正在被使用");
			
			String merchantPublicKey =  redisService.get(cBean.getMerchantNo()+"publicKey").toString();

			// 使用商户公钥验签
			logger.info("使用商户公钥验签");
			if (!RSAHelper.verify(oldstrBody, merchantPublicKey, strBody)) {
				throw new MyException(ExceptionEnum.PLATFORM_IS_ERROR);
			}
			;
			logger.info("商户公钥验签成功");

			ServiceProvideBean spBean = queryProvideByIdService.queryServiceById(cBean.getProvideId());
			String serviceNamePath = spBean.getServiceurl();
			logger.info("动态获取服务路径======{}",serviceNamePath);
			String serviceMethod = spBean.getServicemethod();
			logger.info("动态获取服务方法名====={}",serviceMethod);
			
			// 通过hsf调用身份鉴权
			logger.info("开始通过hsf调用身份鉴权");
			identityAuthService.identityAuth(cBean.getMerchantNo(), cBean.getProvideId());
			ConsumerService consumerFactory = ServiceFactory.consumer();
			consumerFactory.service(serviceNamePath).version(version).group(serviceGroup).addressWaitTime(timeout);
			consumerFactory.sync();
			
		    InterfaceInvocationHandler invokeHandler = new InterfaceInvocationHandler(consumerFactory.subscribe());
			
		    // 通过hsf调用查询天气明细
		    logger.info("开始通过反射，hsf调用查询服务");
		    
			Class<?> clazzService = Class.forName(serviceNamePath);
			// 通过反射调用方法
			Method method = clazzService.getDeclaredMethod(serviceMethod, String.class, String.class);
			
			Object a = new Object();
			
			Object objectBean = invokeHandler.invoke(a,method, new String[]{cBean.getMerchantNo(), cBean.getContent()});
			
			String oldObjectBean = JSONObject.toJSONString(objectBean);
			
			//通过反射获取remark的值
			Field field = objectBean.getClass().getDeclaredField("remark");
			field.setAccessible(true);
			Object remark = field.get(objectBean);
			//判断调用是否成功
		      String isSuccess="1";
		      if(remark!=null){
		        isSuccess="0";
		      }
		      // 通过hsf调用记录平台流水
		      logger.info("开始通过hsf调用记录平台流水");
		      platformFlowService.platformFlow(cBean.getFlow(), oldstrBody, oldObjectBean,
		    		  cBean.getMerchantNo(), cBean.getProvideId(),isSuccess,startTime);
		      // 通过mq异步调用计费、统计
		      logger.info("开始通过mq异步调用计费、统计");
		      aliMQUtil.sendMessage(topic, tag, "fxhm_2018", oldstrBody.getBytes());
			if( remark != null){
				return ResultUtil.error("-1", remark.toString());
			}else{
				// 使用平台私钥签名
				logger.info("使用平台私钥签名");
				String airStr = RSAHelper.sign(oldObjectBean, platformPrivateKey);
				
				map.put("oldAirStr", oldObjectBean);
				map.put("airStr", airStr);
			}

//			Thread.sleep(3000);// 放大资源占用时间，便于观察
			
		} catch (Exception e) {
			e.printStackTrace();
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			logger.info("释放一个资源");
			redisService.decr(provideNum,1);
		}
		return ResultUtil.success(map);

	}
}
